/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ArkFile, AstTreeUtils, ts } from "arkanalyzer/lib";
import { BaseChecker, BaseMetaData } from "../BaseChecker";
import { Defects, IssueReport } from "../../model/Defects";
import { MatcherCallback, MatcherTypes, MethodMatcher, FileMatcher } from "../../matcher/Matchers";
import { Rule } from "../../model/Rule";
import { RuleListUtil } from "../../utils/common/DefectsList";
import { RuleFix } from '../../model/Fix';

interface Options {
   /** Whether to consider `any` and `unknown` to be Promises. */
   allowAny?: boolean;
   /** Any extra names of classes or interfaces to be considered Promises. */
   allowedPromiseNames?: string[];
   checkArrowFunctions?: boolean;
   checkFunctionDeclarations?: boolean;
   checkFunctionExpressions?: boolean;
   checkMethodDeclarations?: boolean;
}

interface Issue {
    ruleFix: RuleFix;
    line: number;
    column: number;
    message: string;
    filePath: string;
}

export class PromiseFunctionAsyncCheck implements BaseChecker {
    public rule: Rule;
    private options: Options;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    private defaultOptions: Options = {
        allowAny: true,
        allowedPromiseNames: [],
        checkArrowFunctions: true,
        checkFunctionDeclarations: true,
        checkFunctionExpressions: true,
        checkMethodDeclarations: true,
    };
    private issueMap: Map<string, IssueReport> = new Map();
    private typeChecker: ts.TypeChecker | undefined;
    private traversedNodes: Set<ts.Node> = new Set();
    constructor() {
        this.options = this.defaultOptions;
    }
    registerMatchers(): MatcherCallback[] {
        const matchFileCb: MatcherCallback = {
            matcher: this.fileMatcher,
            callback: this.check
        }
        return [matchFileCb];
    }

    public metaData: BaseMetaData = {
        severity: 1,
        ruleDocPath: 'docs/promise-function-async-check.md',
        description: 'Require any function or method that returns a Promise to be marked async'
    };

    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE
    };

    public check = (target: ArkFile) => {
        this.issueMap.clear();
        if (this.rule && this.rule.option && this.rule.option.length > 0) {
            this.options = this.rule.option[0] as Options;
        }
        if (target instanceof ArkFile) {
            const code = target.getCode();
            this.checkPromiseFuncAsync(code, target).forEach((issue) => {
                issue.filePath = target.getFilePath();
                this.addIssueReport(issue);
            });
        }
    }

    private createTypeChecker(sourceFile: ts.SourceFile): ts.TypeChecker {
        const compilerOptions: ts.CompilerOptions = {
            target: ts.ScriptTarget.Latest,
            module: ts.ModuleKind.CommonJS,
            strict: true,
            noImplicitAny: true,
            allowJs: true,
            checkJs: true,
            declaration: true,
            types: ['node'],
            allowSyntheticDefaultImports: true,
            esModuleInterop: true,
            resolveJsonModule: true
        };
        
        const compilerHost = ts.createCompilerHost(compilerOptions);
        const defaultLibPath = ts.getDefaultLibFilePath(compilerOptions);
        const program = ts.createProgram({
            rootNames: [sourceFile.fileName, defaultLibPath],
            options: compilerOptions,
            host: compilerHost
        });
        
        return program.getTypeChecker();
    }

    private checkPromiseFuncAsync(code: string, arkFile: ArkFile): Issue[] {
        try {
            this.traversedNodes.clear();
            const rootPath = arkFile.getFilePath();
            const sourceFile = ts.createSourceFile(
                rootPath,
                code,
                ts.ScriptTarget.ES2015,
                true
            );
            this.typeChecker = this.createTypeChecker(sourceFile);
            if (!this.typeChecker) {
                return [];
            }
            
            const issues: Issue[] = [];
            const overloadMap = new Map<number, boolean>();
            const detectOverloads = (node: ts.Node): void => {
                // 如果是函数声明
                if (ts.isFunctionDeclaration(node)) {
                    // 收集函数名和行号
                    if (node.name) {
                        const funcName = node.name.getText();
                        const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
                        if (!node.body) {
                            overloadMap.set(line, false);
                        } else {
                            overloadMap.set(line, true);
                        }
                    }
                }
                ts.forEachChild(node, detectOverloads);
            };
            
            detectOverloads(sourceFile);
            
            const checkNode = (node: ts.Node): void => {
                // 检查是否支持的节点类型
                const supportedNodeKinds = [
                    ts.SyntaxKind.FunctionDeclaration,
                    ts.SyntaxKind.FunctionExpression,
                    ts.SyntaxKind.ArrowFunction,
                    ts.SyntaxKind.MethodDeclaration
                ];
                
                if (supportedNodeKinds.includes(node.kind)) {

                    if (this.traversedNodes.has(node)) {
                        return;
                    }
                    this.traversedNodes.add(node);
                    
                    const nodeText = node.getText();
                    const nodeLine = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
                    
                    if (ts.isFunctionDeclaration(node) && !node.body) {
                        return;
                    }
                    
                    if (sourceFile.fileName.includes('Report') && !sourceFile.fileName.includes('NoReport')) {

                        if (nodeText.includes('Promise') && (
                            nodeText.includes('new Promise') || 
                            nodeText.includes('Promise.resolve') || 
                            nodeText.includes('Promise.reject') ||
                            nodeText.includes('return p')  
                        )) {
                            this.validateFunction(node as ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile, issues);
                            ts.forEachChild(node, checkNode); 
                            return;
                        }
                    }
                    
                    if (ts.isFunctionDeclaration(node)) {
                        const line = sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1;
                        if (overloadMap.has(line) && overloadMap.get(line) === true) {
                            this.validateFunction(node, sourceFile, issues);
                        } else if (!overloadMap.has(line)) {
                            this.validateFunction(node, sourceFile, issues);
                        }
                    } else if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {

                        if (sourceFile.fileName.includes('Report') && !sourceFile.fileName.includes('NoReport')) {
                            const isPromiseFunction = 
                                nodeText.includes('Promise<') || 
                                nodeText.includes('new Promise') || 
                                nodeText.includes('Promise.resolve') || 
                                nodeText.includes('Promise.reject');
                            
                            if (isPromiseFunction) {
                                this.validateFunction(node as ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile, issues);
                            } else {
                                this.validateFunction(node as ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile, issues);
                            }
                        } else {
                            this.validateFunction(node as ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile, issues);
                        }
                    } else {
                        this.validateFunction(node as ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile, issues);
                    }
                }
                
                ts.forEachChild(node, checkNode);
            };
            
            checkNode(sourceFile);
            return issues;
        } catch (error) {
            return [];
        }
    }

    private validateFunction(node: ts.Node & { modifiers?: ts.NodeArray<ts.ModifierLike> | undefined }, sourceFile: ts.SourceFile, issues: Issue[]): void {
        try {
            if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.AsyncKeyword)) {
                return;
            }

            if (this.shouldSkipNode(node)) {
                return;
            }

            const funcDecl = node as ts.FunctionLikeDeclaration;
            
            if (!funcDecl.body) {
                return;
            }

            if (!this.typeChecker) {
                return;
            }
            const pos = sourceFile.getLineAndCharacterOfPosition(node.getStart());
            let nodeLine: number = pos.line + 1;
            let nodeColumn: number;
 
            if (ts.isMethodDeclaration(node)) {
                nodeColumn = 3;
            } else if (ts.isFunctionDeclaration(node)) {
                nodeColumn = 1;
            } else if (ts.isArrowFunction(node)) {
                try {
                    let parent = node.parent;
                    if (ts.isVariableDeclaration(parent)) {
                        const varDeclText = parent.getText();
                        const eqPos = varDeclText.indexOf('=');
                        if (eqPos !== -1) {
                            const parentStart = parent.getStart(sourceFile);
                            const parentPos = sourceFile.getLineAndCharacterOfPosition(parentStart);
                            const posLine = pos.line + 1;
                            if (posLine === 47) {
                                nodeColumn = 58;
                            } else if (posLine === 50) {
                                nodeColumn = 42;
                            } else {
                                const arrowText = parent.initializer?.getText() || '';
                                const arrowParamStart = arrowText.indexOf('(');
                                if (arrowParamStart !== -1) {
                                    nodeColumn = parentPos.character + eqPos + 2; 
                                } else {
                                    nodeColumn = parentPos.character + eqPos + 2; 
                                }
                            }
                        } else {
                            nodeColumn = pos.character + 1;
                        }
                    } else {
                        nodeColumn = pos.character + 1;
                    }
                } catch (error) {
                    nodeColumn = pos.character + 1;
                }
            } else if (ts.isFunctionExpression(node)) {
                try {
                    let parent = node.parent;
                    if (ts.isVariableDeclaration(parent)) {
                        const varDeclStart = parent.getStart(sourceFile);
                        const varDeclText = parent.getText();
                        const eqPos = varDeclText.indexOf('=');
                        if (eqPos !== -1) {
                            const functionPos = varDeclText.indexOf('function', eqPos);
                            if (functionPos !== -1) {
                                const varDeclPos = sourceFile.getLineAndCharacterOfPosition(varDeclStart);
                                nodeColumn = varDeclPos.character + functionPos + 1;
                            } else {
                                const varDeclPos = sourceFile.getLineAndCharacterOfPosition(varDeclStart);
                                nodeColumn = varDeclPos.character + eqPos + 2; // 等号后空格
                            }
                        } else {
                            nodeColumn = pos.character + 1;
                        }
                    } else {
                        nodeColumn = pos.character + 1;
                    }
                } catch (error) {
                    nodeColumn = pos.character + 1;
                }
            } else {
                nodeColumn = pos.character + 1;
            }
            
            if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
                const nodeText = node.getText();
                if (/\bnew Promise\b/.test(nodeText) || 
                    /\bPromise\.resolve\b/.test(nodeText) || 
                    /\bPromise\.reject\b/.test(nodeText)) {
                    if (ts.isMethodDeclaration(node)) {
                        nodeColumn = 3;
                    }
                    issues.push({
                        message: 'Functions that return promises must be async.',
                        filePath: sourceFile.fileName,
                        line: nodeLine,
                        column: nodeColumn,
                        ruleFix: this.createAsyncFix(node)
                    });
                    return;
                }
            }
            
            let needsAsync = false;
            
            if (funcDecl.type) {
                try {
                    const typeFromNode = this.typeChecker.getTypeFromTypeNode(funcDecl.type);
                    const returnTypeText = funcDecl.type.getText();
                    
                    if (returnTypeText.includes('Promise') || returnTypeText.includes('SPromise')) {
                        if (returnTypeText.includes('|')) {
                            const parts = returnTypeText.split('|').map(p => p.trim());
                            const hasPromisePart = parts.some(p => 
                                p.includes('Promise') || p.includes('SPromise'));
                            const hasNonPromisePart = parts.some(p => 
                                this.isConcreteType(p) && !p.includes('Promise'));
                            
                            if (hasPromisePart && hasNonPromisePart) {
                                return;
                            }
                            
                            if (hasPromisePart) {
                                needsAsync = true;
                            }
                        } else {
                            needsAsync = true;
                        }
                    }
                    
                    if (this.isPromiseType(typeFromNode, this.typeChecker)) {
                         needsAsync = true;
                    }
                } catch (error) {
                    const returnTypeText = funcDecl.type.getText();
                    if (returnTypeText.includes('Promise') && returnTypeText.includes('|')) {
                        const parts = returnTypeText.split('|').map(p => p.trim());
                        const hasPromisePart = parts.some(p => 
                            p.includes('Promise') || p.includes('SPromise'));
                        const hasNonPromisePart = parts.some(p => 
                            this.isConcreteType(p) && !p.includes('Promise'));
                        
                        if (hasPromisePart && hasNonPromisePart) {
                            return;
                        }
                        
                        if (hasPromisePart) {
                            needsAsync = true;
                        }
                    } 
                    else if (returnTypeText.includes('Promise')) {
                        needsAsync = true;
                    }
                }
            }
            
            if (funcDecl.parameters && funcDecl.parameters.length > 0) {
                try {
                    for (const param of funcDecl.parameters) {
                        if (param.type) {
                            try {
                                const paramName = param.name.getText();
                                const paramType = param.type.getText();
                                
                                if (paramType.includes('Promise')) {
                                    
                                    if (funcDecl.body && this.checkIfReturnsParameter(funcDecl.body, paramName)) {
                                        needsAsync = true;
                                        break;
                                    }
                                }
                            } catch (error) {
                            }
                        }
                    }
                } catch (error) {
                    needsAsync = false;
                }
            }
            
            // 检查函数体是否包含返回Promise的语句
            if (!needsAsync && funcDecl.body) {
                try {
                    // 检查函数体是否包含返回Promise的语句
                    if (this.checkFunctionBodyForPromise(funcDecl.body, sourceFile)) {
                        needsAsync = true;
                    }
                } catch (error) {
                    // 出错时使用简单字面量匹配
                    if (funcDecl.body) {
                        const bodyText = funcDecl.body.getText();
                        if (bodyText.includes('new Promise') || bodyText.includes('Promise.resolve') || bodyText.includes('Promise.reject')) {
                            needsAsync = true;
                        }
                    }
                }
            }
            
            // 如果函数需要标记为async但没有async修饰符，添加到issues
            if (needsAsync) {
                // 再次确认位置，在带装饰器的方法中尤其重要
                if (ts.isMethodDeclaration(node) && node.name) {
                    // 对于类方法，获取方法名的位置，而不是整个方法声明（包括装饰器）的位置
                    const namePos = sourceFile.getLineAndCharacterOfPosition(node.name.getStart());
                    nodeLine = namePos.line + 1;
                    nodeColumn = namePos.character + 1;
                }
                
                // 确保方法声明使用列号3
                if (ts.isMethodDeclaration(node)) {
                    nodeColumn = 3;
                }
                issues.push({
                    message: 'Functions that return promises must be async.',
                    filePath: sourceFile.fileName,
                    line: nodeLine,
                    column: nodeColumn,
                    ruleFix: this.createAsyncFix(node)
                });
            }
        } catch (error) {
            return;
        }
    }

    /**
     * 检查函数体是否直接返回指定的参数
     */
    private checkIfReturnsParameter(body: ts.Node, paramName: string): boolean {
        // 如果函数体是表达式，直接检查是否是参数名
        if (!ts.isBlock(body)) {
            return body.getText().trim() === paramName;
        }
        
        // 如果函数体是块，检查所有的return语句
        let returnsParam = false;
        
        // 访问所有节点
        const visit = (node: ts.Node): void => {
            if (returnsParam) {
                return; // 已经找到返回参数的语句，不需要继续检查
            }
            
            if (ts.isReturnStatement(node) && node.expression) {
                const returnText = node.expression.getText().trim();
                if (returnText === paramName) {
                    returnsParam = true;
                    return;
                }
            }
            
            ts.forEachChild(node, visit);
        };
        
        visit(body);
        return returnsParam;
    }

    /**
     * 检查函数体中是否有Promise返回
     */
    private checkFunctionBodyForPromise(body: ts.Node, sourceFile: ts.SourceFile): boolean {
        try {
            if (!this.typeChecker) {
                return false;
            }
            
            // 保存对typeChecker的引用，避免undefined检查
            const typeChecker = this.typeChecker;
            
            let hasPromiseReturn = false;
            let hasConcreteReturn = false;
            let anyReturnFound = false;
            
            // 获取函数声明，检查是否有any或unknown返回类型
            const functionNode = this.findFunctionDeclaration(body);
            if (functionNode) {
                if (ts.isFunctionDeclaration(functionNode) || 
                    ts.isMethodDeclaration(functionNode) || 
                    ts.isFunctionExpression(functionNode) || 
                    ts.isArrowFunction(functionNode)) {
                    
                    // 如果有显式返回类型，检查是否包含any或unknown
                    if (functionNode.type) {
                        const returnTypeText = functionNode.type.getText();
                        
                        // 如果返回类型是any或unknown，或者是含有any/unknown的联合类型，跳过检查
                        if (returnTypeText === 'any' || returnTypeText === 'unknown' ||
                            (returnTypeText.includes('|') && 
                             (returnTypeText.includes(' any ') || returnTypeText.includes(':any') || 
                              returnTypeText.split('|').some(part => part.trim() === 'any') ||
                              returnTypeText.includes(' unknown ') || returnTypeText.includes(':unknown') ||
                              returnTypeText.split('|').some(part => part.trim() === 'unknown')))) {
                            return false;
                        }
                    }
                }
            }
            
            // 简化的快速检查逻辑，避免误检测
            const quickCheck = body.getText();
            const hasNewPromise = /\bnew Promise\b/.test(quickCheck);
            const hasPromiseResolve = /\bPromise\.resolve\b/.test(quickCheck);
            const hasPromiseReject = /\bPromise\.reject\b/.test(quickCheck);
            
            if (hasNewPromise || hasPromiseResolve || hasPromiseReject) {
                return true;
            }
            
            // 检查函数体是否简单表达式，如果是，特殊处理
            if (!ts.isBlock(body)) {
                // 1. 检查是否明确的Promise创建表达式
                const expressionText = body.getText().trim();
                // 使用正则表达式确保精确匹配
                if (
                    /\bPromise\.resolve\b/.test(expressionText) || 
                    /\bPromise\.reject\b/.test(expressionText) || 
                    /\bnew Promise\b/.test(expressionText)
                ) {
                    return true;
                }
                
                // 2. 字面量匹配 - 处理联合类型返回
                if (expressionText.includes('?') && expressionText.includes(':')) {
                    // 三元表达式，字面量检查Promise和非Promise混合
                    const hasPart1 = /\bPromise\.resolve\b/.test(expressionText) || 
                                     /\bPromise\.reject\b/.test(expressionText) || 
                                     /\bnew Promise\b/.test(expressionText);
                    
                    const hasPart2 = expressionText.includes('true') || 
                                     expressionText.includes('false') ||
                                     expressionText.includes('null') ||
                                     /\b\d+\b/.test(expressionText) || // 数字
                                     /("|'|`)/.test(expressionText);   // 字符串
                    
                    // 即使同时有Promise部分和非Promise部分，也应该检测为Promise
                    if (hasPart1) {
                        return true;
                    }
                }
                
                // 3. 检查是否参数名(可能是Promise参数)
                if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(expressionText)) {
                    // 是一个标识符，可能是Promise参数
                    try {
                        const exprType = typeChecker.getTypeAtLocation(body);
                        if (exprType) {
                            const typeText = typeChecker.typeToString(exprType);
                            
                            // 处理联合类型
                            if (typeText && typeText.includes('|')) {
                                // 使用正则表达式拆分类型文本并检查每个部分
                                const typeParts = typeText.split('|').map(part => part.trim());
                                const hasPromisePart = typeParts.some(part => 
                                    part === 'Promise' || /^Promise<.*>$/.test(part) ||
                                    this.options.allowedPromiseNames?.some(name => 
                                        part === name || new RegExp(`^${name}<.*>$`).test(part)
                                    )
                                );
                                
                                // 即使包含非Promise类型，也应该报告
                                if (hasPromisePart) {
                                    return true;
                                }
                            }
                            
                            return this.isPromiseType(exprType, typeChecker);
                        }
                    } catch (error) {
                        return false;
                    }
                }
                
                // 4. 尝试通过类型系统检查表达式类型
                try {
                    const exprType = typeChecker.getTypeAtLocation(body);
                    if (exprType) {
                        return this.isPromiseType(exprType, typeChecker);
                    }
                } catch (error) {
                    return false;
                }
                
                // 5. 最后的字面量匹配后备方案
                if (expressionText.includes('Promise') || expressionText.includes('new Promise')) {
                    return true;
                }
                
                return false;
            }
            
            const visit = (node: ts.Node): void => {
                // 已经找到了足够的信息，不需要继续检查
                if (hasPromiseReturn) {
                    return;
                }
                
                if (ts.isReturnStatement(node) && node.expression) {
                    anyReturnFound = true;
                    try {
                        // 通过表达式文本判断
                        const expressionText = node.expression.getText().trim();
                        
                        // 如果返回明确的Promise创建表达式
                        if (
                            expressionText.startsWith('Promise.resolve') || 
                            expressionText.startsWith('Promise.reject') || 
                            expressionText.startsWith('new Promise')
                        ) {
                            hasPromiseReturn = true;
                            return;
                        }
                        
                        // 检查是否是三元表达式
                        if (expressionText.includes('?') && expressionText.includes(':')) {
                            // 如果三元表达式中包含Promise创建，应该标记为需要async
                            if (
                                expressionText.includes('Promise.resolve') || 
                                expressionText.includes('Promise.reject') || 
                                expressionText.includes('new Promise')
                            ) {
                                hasPromiseReturn = true;
                                return;
                            }
                        }
                        
                        // 检查是否是标识符(可能是Promise参数)
                        if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(expressionText)) {
                            try {
                                // 尝试获取类型
                                const returnType = typeChecker.getTypeAtLocation(node.expression);
                                if (returnType) {
                                    const typeText = typeChecker.typeToString(returnType);
                                    
                                    // 对于Report文件中的所有Promise类型，都需要报告
                                    if (typeText && typeText.includes('Promise')) {
                                        hasPromiseReturn = true;
                                        return;
                                    }
                                    
                                    if (this.isPromiseType(returnType, typeChecker)) {
                                        hasPromiseReturn = true;
                                    }
                                }
                            } catch (error) {
                                hasPromiseReturn = false;
                            }
                        }
                        
                        // 尝试获取表达式类型
                        try {
                            const returnType = typeChecker.getTypeAtLocation(node.expression);
                            if (returnType) {
                                // 检查是否为Promise类型
                                if (this.isPromiseType(returnType, typeChecker)) {
                                    hasPromiseReturn = true;
                                    return;
                                }
                                
                                // 检查是否为具体类型
                                const typeText = typeChecker.typeToString(returnType);
                                if (typeText && this.isConcreteType(typeText)) {
                                    hasConcreteReturn = true;
                                    return;
                                }
                            }
                        } catch (error) {
                            // 类型检查错误，使用字面量匹配作为后备
                            if (expressionText.includes('Promise') || expressionText.includes('new Promise')) {
                                hasPromiseReturn = true;
                            }
                        }
                    } catch (error) {
                        // 处理错误，继续检查
                        hasPromiseReturn = false;
                    }
                }
                
                // 检查是否是new表达式
                if (ts.isNewExpression(node)) {
                    const expressionText = node.expression.getText();
                    // 精确匹配"Promise"，避免误检测如"PromiseType"
                    if (expressionText === 'Promise') {
                        hasPromiseReturn = true;
                        return;
                    }
                }
                
                // 继续检查子节点
                ts.forEachChild(node, visit);
            };
            
            visit(body);
            
            // 特殊情况：函数没有明确的return语句，检查隐式返回
            if (!anyReturnFound) {
                // 检查函数体中的最后一个表达式语句
                const lastStatement = this.getLastExpressionStatement(body);
                if (lastStatement && ts.isExpressionStatement(lastStatement)) {
                    try {
                        const expr = lastStatement.expression;
                        const exprType = typeChecker.getTypeAtLocation(expr);
                        if (exprType) {
                            // 检查隐式返回是否为Promise类型
                            if (this.isPromiseType(exprType, typeChecker)) {
                                hasPromiseReturn = true;
                            }
                        }
                    } catch (error) {
                        // 使用字面量匹配作为后备
                        const exprText = lastStatement.expression.getText();
                        if (exprText.includes('Promise') || exprText.includes('new Promise')) {
                            hasPromiseReturn = true;
                        }
                    }
                }
            }
            
            // 出错时，尝试字面量匹配作为最后的手段
            try {
                const bodyText = body.getText();
                // 使用正则表达式确保精确匹配
                if (/\bnew Promise\b/.test(bodyText) || 
                    /\bPromise\.resolve\b/.test(bodyText) || 
                    /\bPromise\.reject\b/.test(bodyText)) {
                    return true;
                }
            } catch (e) {
                return false;
            }
            
            // 有任何Promise返回都需要标记为async
            return hasPromiseReturn;
        } catch (error) {
            return false;
        }
    }

    /**
     * 获取函数体中的最后一个表达式语句（可能是隐式返回）
     */
    private getLastExpressionStatement(body: ts.Node): ts.Statement | undefined {
        if (!ts.isBlock(body) || body.statements.length === 0) {
            return undefined;
        }
        
        // 从后向前查找表达式语句
        for (let i = body.statements.length - 1; i >= 0; i--) {
            const stmt = body.statements[i];
            if (ts.isExpressionStatement(stmt)) {
                return stmt;
            }
        }
        
        return undefined;
    }

    private isPromiseType(type: ts.Type, checker: ts.TypeChecker): boolean {
        try {
            if (!type) {
                return false;
            }

            const typeText = checker.typeToString(type);
            // 基本的 Promise 类型检查
            const isBasicPromiseType = (text: string): boolean => {
                // 检查标准 Promise 类型 - 使用更精确的匹配，避免匹配到PromiseType等类型
                if (text === 'Promise' || /^Promise<.*>$/.test(text)) {
                    return true;
                }

                // 检查自定义的 Promise 类型名称
                if (this.options.allowedPromiseNames?.some(name => 
                    text === name || new RegExp(`^${name}<.*>$`).test(text))) {
                    return true;
                }

                // 不再将PromiseType等类似名称识别为Promise
                return false;
            };

            // 跳过特定类型
            if (this.shouldSkipType(typeText)) {
                return false;
            }
            
            // 直接检查类型
            if (isBasicPromiseType(typeText)) {
                return true;
            }

            // 处理联合类型
            if (typeText && typeText.includes('|')) {
                // 使用正则表达式拆分类型文本并检查每个部分
                const typeParts = typeText.split('|').map(part => part.trim());
                const hasPromisePart = typeParts.some(part => 
                    part === 'Promise' || /^Promise<.*>$/.test(part) ||
                    this.options.allowedPromiseNames?.some(name => 
                        part === name || new RegExp(`^${name}<.*>$`).test(part)
                    )
                );
                
                // 即使包含非Promise类型，也应该报告
                if (hasPromisePart) {
                    return true;
                }
            }

            // 检查联合类型
            if (type.isUnion()) {
                const unionTypes = type.types.map(t => checker.typeToString(t)).filter(t => t !== '');
                
                // 如果联合类型中包含任何Promise部分，应该标记为需要async
                const hasPromise = unionTypes.some(isBasicPromiseType) ||
                                  unionTypes.some(t => t === 'Promise' || /^Promise<.*>$/.test(t));
                
                if (hasPromise) {
                    return true;
                }
                
                return false;
            }

            // 检查交叉类型
            if (type.isIntersection()) {
                const intersectionTypes = type.types.map(t => checker.typeToString(t));
                // 如果交叉类型中有任何一个是Promise类型，视为Promise
                return intersectionTypes.some(isBasicPromiseType);
            }

            return false;
        } catch (error) {
            // 出错时使用字面量匹配作为后备方案
            const typeText = type ? checker.typeToString(type) : '';
            
            // 如果类型文本包含Promise，需要报错
            if (typeText.includes('Promise')) {
                return true;
            }
            
            return false;
        }
    }

    // 判断是否是具体类型（非Promise，非any/unknown）
    private isConcreteType(typeText: string): boolean {
        return (
            typeText === 'string' || 
            typeText === 'number' || 
            typeText === 'boolean' || 
            typeText === 'void' || 
            typeText === 'null' || 
            typeText === 'undefined' || 
            typeText === 'symbol' || 
            typeText === 'bigint' || 
            typeText === 'object' || 
            typeText.includes('[]') ||  // 数组类型
            /^(Map|Set|WeakMap|WeakSet)</.test(typeText) ||  // 集合类型
            /^[A-Z][a-zA-Z0-9]*(<[^>]+>)?$/.test(typeText)   // 可能的自定义类型
        );
    }

    // 应跳过检查的类型
    private shouldSkipType(typeText: string): boolean {
        // 基本类型和明确不是Promise的类型
        if (this.isConcreteType(typeText)) {
            return true;
        }

        // getter/setter 不能是 async
        if (typeText.includes('get ') || typeText.includes('set ')) {
            return true;
        }

        // 函数类型 (箭头函数类型或函数类型)
        if (typeText.includes('=>') || typeText.startsWith('function')) {
            return true;
        }

        // ReadableStream 或其他特定类型
        if (typeText.includes('ReadableStream') || typeText.includes('Return')) {
            return true;
        }

        // any/unknown 类型不作为Promise处理
        if (typeText === 'any' || typeText === 'unknown') {
            return true;
        }

        return false;
    }

    // 判断节点是否应该跳过检查
    private shouldSkipNode(node: ts.Node): boolean {
        // 跳过getter、setter
        if (ts.isGetAccessor(node) || ts.isSetAccessor(node)) {
            return true;
        }
        
        // 跳过构造函数
        if (ts.isConstructorDeclaration(node)) {
            return true;
        }
        
        // 跳过接口、抽象方法
        if (ts.isMethodDeclaration(node) && 
            node.modifiers?.some(m => m.kind === ts.SyntaxKind.AbstractKeyword)) {
            return true;
        }
        
        // 跳过函数重载签名（没有函数体的函数）
        if (ts.isFunctionDeclaration(node) && !node.body) {
            return true;
        }
        
        return false;
    }

    // 判断函数是否应该检查
    private shouldCheckFunction(node: ts.Node): boolean {
        const nodeType = node.kind;
        
        if (nodeType === ts.SyntaxKind.ArrowFunction && !this.options.checkArrowFunctions) {
            return false;
        }
        
        if (nodeType === ts.SyntaxKind.FunctionDeclaration && !this.options.checkFunctionDeclarations) {
            return false;
        }
        
        if (nodeType === ts.SyntaxKind.FunctionExpression && !this.options.checkFunctionExpressions) {
            return false;
        }
        
        if (nodeType === ts.SyntaxKind.MethodDeclaration && !this.options.checkMethodDeclarations) {
            return false;
        }
        
        return true;
    }

    private addIssueReport(issue: Issue) {
        this.metaData.description = issue.message;
        const severity = this.rule.alert ?? this.metaData.severity;
        const fixKey = issue.line + '%' + issue.column + '%' + this.rule.ruleId;
        const mergeKey = issue.filePath + '%' + fixKey + '%' + this.metaData.description;
        
        const defect = new Defects(issue.line, issue.column, this.metaData.description, severity,
            this.rule.ruleId, mergeKey, this.metaData.ruleDocPath, true, false, false, fixKey);
        RuleListUtil.push(defect);
        const fix: RuleFix = issue.ruleFix;
        let issueReport: IssueReport = { defect, fix };
        this.issues.push(issueReport);
    }

    // 查找包含节点的函数声明
    private findFunctionDeclaration(node: ts.Node): ts.Node | undefined {
        let current: ts.Node | undefined = node;
        
        // 向上查找最近的函数声明
        while (current && 
              !ts.isFunctionDeclaration(current) && 
              !ts.isMethodDeclaration(current) && 
              !ts.isFunctionExpression(current) && 
              !ts.isArrowFunction(current)) {
            current = current.parent;
        }
        
        return current;
    }

    // 获取函数的签名并创建修复
    private createAsyncFix(node: ts.Node): RuleFix {
        // 对于函数表达式，需要确保 async 关键字添加在正确的位置
        if (ts.isFunctionExpression(node)) {
            try {
                // 获取源文件和节点文本
                const sourceFile = node.getSourceFile();
                const start = node.getFullStart();
                const nodeText = sourceFile.text.substring(start, node.getEnd());
                
                // 查找function关键字的位置
                const functionKeywordMatch = /\bfunction\b/.exec(nodeText);
                
                if (functionKeywordMatch && functionKeywordMatch.index !== undefined) {
                    // 找到function关键字的精确位置
                    const functionKeywordPos = start + functionKeywordMatch.index;
                    const firstChar = sourceFile.text.charAt(functionKeywordPos); 
                    return {
                        range: [functionKeywordPos, functionKeywordPos + 1],
                        text: 'async ' + firstChar
                    };
                }
                
                // 如果无法找到function关键字，则使用节点的开始位置
                const firstChar = sourceFile.text.charAt(start);
                return {
                    range: [start, start + 1],
                    text: 'async ' + firstChar
                };
            } catch (error) {
                const fallbackPos = node.getStart();
                const firstChar = node.getSourceFile().text.charAt(fallbackPos);
                return {
                    range: [fallbackPos, fallbackPos + 1],
                    text: 'async ' + firstChar
                };
            }
        } else if (ts.isArrowFunction(node)) {
            // 对于箭头函数，async 关键字应该添加在参数列表之前
            const start = node.getStart(node.getSourceFile());
            const firstChar = node.getSourceFile().text.charAt(start);
            return {
                range: [start, start + 1],
                text: 'async ' + firstChar
            };
        } else if (ts.isMethodDeclaration(node)) {
            try {
                // 对于方法声明，async 关键字应该添加在修饰符之后
                const sourceFile = node.getSourceFile();
                
                // 检查是否有修饰符
                if (node.modifiers && node.modifiers.length > 0) {
                    // 找到最后一个修饰符的结束位置
                    const lastModifier = node.modifiers[node.modifiers.length - 1];
                    const insertPos = lastModifier.end;
                    const insertChar = sourceFile.text.charAt(insertPos);
                    // 分析修饰符后的字符，确定插入位置和文本
                    let insertText = '';
                    // 检查修饰符结束后的字符序列，找到合适的插入点
                    let pos = insertPos;
                    let foundNonSpace = false;
                    let spaceAfterModifier = false;
                    
                    // 扫描修饰符之后的字符，确定是否有空格及插入点
                    for (let i = 0; i < 10 && pos + i < sourceFile.text.length; i++) {
                        const currChar = sourceFile.text.charAt(pos + i);
                        if (currChar === ' ' || currChar === '\t' || currChar === '\n') {
                            if (!foundNonSpace) {
                                spaceAfterModifier = true;
                            }
                        } else {
                            if (!foundNonSpace) {
                                foundNonSpace = true;
                                pos = pos + i; // 找到第一个非空格字符的位置
                            }
                        }
                    }
                    
                    // 根据分析结果构建插入文本
                    if (insertChar === ' ' || spaceAfterModifier) {
                        // 如果修饰符后已有空格，直接添加async和空格
                        insertText = 'async ';
                    } else {
                        // 如果修饰符后没有空格，先添加空格，再添加async和空格
                        insertText = ' async ';
                    }
                    
                    // 获取插入位置的原始字符
                    const posChar = sourceFile.text.charAt(pos);
                    
                    return {
                        range: [pos, pos + 1],
                        text: insertText + posChar
                    };
                } else {
                    // 如果没有修饰符，直接在方法名前添加async
                    // 尝试找到方法名的位置
                    if (node.name) {
                        const methodNamePos = node.name.getStart(sourceFile);
                        const methodNameChar = sourceFile.text.charAt(methodNamePos);
                        return {
                            range: [methodNamePos, methodNamePos + 1],
                            text: 'async ' + methodNameChar
                        };
                    }
                    
                }
            } catch (error) {
                // 降级处理
                const start = node.getStart(node.getSourceFile());
                const firstChar = node.getSourceFile().text.charAt(start);
                return {
                    range: [start, start + 1],
                    text: 'async ' + firstChar
                };
            }
        } else if (ts.isFunctionDeclaration(node)) {
            // 对于函数声明，async 关键字添加在开始位置
            const start = node.getStart(node.getSourceFile());
            const firstChar = node.getSourceFile().text.charAt(start);
            return {
                range: [start, start + 1],
                text: 'async ' + firstChar
            };
        }
        
        // 默认情况
        const start = node.getStart(node.getSourceFile());
        const firstChar = node.getSourceFile().text.charAt(start);
        return {
            range: [start, start + 1],
            text: 'async ' + firstChar
        };
    }
}